package failover

import (
	"github.com/go-mysql-org/go-mysql/mysql"
	"github.com/pingcap/errors"
)

func Failover(flavor string, slaves []*Server) ([]*Server, error) {
	var h Handler
	var err error

	switch flavor {
	case mysql.MySQLFlavor:
		h = new(MysqlGTIDHandler)
	case mysql.MariaDBFlavor:
		return nil, errors.Errorf("MariaDB failover is not supported now")
	default:
		return nil, errors.Errorf("invalid flavor %s", flavor)
	}

	if err := h.CheckGTIDMode(slaves); err != nil {
		return nil, errors.Trace(err)
	}

	for _, slave := range slaves {
		if err = h.WaitRelayLogDone(slave); err != nil {
			return nil, errors.Trace(err)
		}
	}

	var bestSlave *Server
	if bestSlaves, err := h.FindBestSlaves(slaves); err != nil {
		return nil, errors.Trace(err)
	} else {
		bestSlave = bestSlaves[0]
	}

	if err = h.Promote(bestSlave); err != nil {
		return nil, errors.Trace(err)
	}

	for i := 0; i < len(slaves); i++ {
		if bestSlave == slaves[i] {
			continue
		}

		if err = h.ChangeMasterTo(slaves[i], bestSlave); err != nil {
			return nil, errors.Trace(err)
		}
	}

	return slaves, nil
}
